package uk.ac.bath.genetic.plant;

import uk.ac.bath.genetic.bool.Int;
import uk.ac.bath.genetic.bool.Off;
import uk.ac.bath.genetic.bool.Link;
import uk.ac.bath.genetic.bool.And;
import uk.ac.bath.genetic.bool.Or;

import uk.ac.bath.genetic.bool.On;
import uk.ac.bath.genetic.bool.Not;
import uk.ac.bath.genetic.bool.LogicalMachine;
import uk.ac.bath.genetic.component.Point2DInt;
import uk.ac.bath.genetic.component.FoodSupply;
import uk.ac.bath.genetic.base.Point;
import uk.ac.bath.genetic.base.Space;
import uk.ac.bath.genetic.mover.Environment;
import uk.ac.bath.genetic.base.Value;

import uk.ac.bath.genetic.base.Cell;
import uk.ac.bath.util.*;
import java.util.*;
import uk.ac.bath.genetic.base.Operator;
import uk.ac.bath.genetic.base.Pallete;
import uk.ac.bath.genetic.base.PalleteIF;

/*
 * Environment.java
 *
 * Created on January 10, 2001, 11:44 AM
 */
public class PlantEnvironment extends Environment {

    double xLight;
    double yLight;
    
    FoodSupply food;
    PalleteIF pallete;
    
    public PlantEnvironment(Space space, double x, double y, FoodSupply food) {
        super(space, null);
        xLight = x;
        yLight = y;
        this.food = food;

        tweaks.addAll(food.getTweaks());
        tweaks.addAll(PlantCell.tweaks);
        tweaks.addAll(LogicalMachine.tweaks);


        Vector<Operator> pal = new Vector<Operator>();
        pal.add(new And());
        pal.add(new Or());
        pal.add(new Not());
        pal.add(new Link());
// 	pallete.add(new X());
// 	pallete.add(new Mult());
        pal.add(new On());
        pal.add(new Off());
        pal.add(new Int());
        pallete=new Pallete(pal,new Value(0.0));

    }

    public double eatFoodAt(Point loc, double amount) {
        return food.eatFoodAt(loc, amount);
    }

    public double getFoodAt(Point loc) {
        return food.getFoodAt(loc);
    }

    public void replenish() {
        food.replenishFood();
    }

//     public double  eatFoodAt(Point loc,double amount) {
// 	return amount;
//     }

//     public double  getFoodAt(Point loc) {
// 	return 10;// food.getFoodValueAt(loc);
//     }

//     public void replenish() {
// 	//	food.replenishFood();
//     }
    public double getLightAt(Point p) {
        Point2DInt p2 = (Point2DInt) p;

        double dx = p2.getX() - xLight;
        double dy = p2.getY() - yLight;
        double d2 = (dx * dx + dy * dy) + 1;
        return 4.0 / d2;

    }


//     public Cell  cellAt(Point p) {

// 	if (!space.contains(p)) return null;
// 	Iterator iter=population_.iterator();

// 	while(iter.hasNext()) {
// 	    Cell cell = (Cell)iter.next();
// 	    if (cell.getPoint().equals(p)) return cell;
// 	}
// 	return null;
//     }
    public Cell createRandomCell() {
        Point p = food.randomPoint();
        if (cellAt(p) != null) {
            return null;
        }
        int nOps = PlantCell.minOperatorsPerCell +
                MyRandom.nextInt(PlantCell.maxOperatorsPerCell.intValue() - PlantCell.minOperatorsPerCell);
        LogicalMachine m = new LogicalMachine(nOps, pallete);

        int cid = Cell.nextId();
        String tag = "P:" + cid;

        return new PlantCell(m, p,
                PlantCell.initialFitness.doubleValue(),
                Cell.nextId(), 0, 0, tag);
    }

//     public double [][] getFoodArray() {
// 	return food.getArray();
//     }
    public FoodSupply getFoodSupply() {
        return food;
    }

    @Override
    public void mutateCell(Cell cell) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

